"""定义工具对象"""
import os.path
import re

from langchain_core.tools import tool, ToolException
from typing import Dict, Any

from tools.llm_tool import llm_call
from tools.pinecone_tool import search_menu_items_with_ids
from tools.amap_tool import check_delivery_range, DistanceMode


def load_prompt(prompt_template_name: str = None) -> str:
    """加载提示词模板"""
    project_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    prompt_dir = os.path.join(project_dir, "prompt", f"{prompt_template_name}.txt")

    with open(prompt_dir, "r", encoding="utf-8") as f:
        return f.read().strip()


# 一般查询使用的工具
@tool
def general_inquiry(query: str, context: str = None) -> str:
    """
    :param query: 用户的问询内容
    :param context: 可选的上下文信息，用于提供更精准的回复
    :return: 针对用户问询的智能回复
    """
    try:
        # 加载提示词
        instruction = load_prompt("general_inquiry")

        # 如果有上下文信息，添加到查询中
        if not context:
            context = ""
        full_query = f"上下文信息：{context}\n\n用户问题：{query}" if context else query

        # 调用LLM获取回复
        response = llm_call(full_query, instruction)

        return response
    except Exception as e:
        raise ToolException(f"普通工具调用失败{str(e)}")


# 菜品查询相关的工具
@tool
def menu_inquiry(query: str, context: str = None) -> Dict[str, Any]:
    """
    :param query: 用户提问
    :param context: 上下文信息
    :return:
    """
    try:
        # 1、从向量数据库中查询当前要查询的菜品 (相似性检索)
        pinecone_result = search_menu_items_with_ids(query)
        similarity_item_list = [item for item in pinecone_result["contents"]]
        similarity_context = "\n".join(similarity_item_list)
        # 2、加载提示词
        instruction = load_prompt("menu_inquiry")
        full_query = ""
        if not context and not similarity_context:
            full_query = query
        if context and similarity_context:
            full_query = f"当前上下文信息是{context}\\n 输入的问题{query}\\尽量基于提供的菜品信息回答问题：\n 当前查询到的菜品信息是{similarity_context}"
        if context and not similarity_context:
            full_query = f"当前上下文信息是{context}\\n 输入的问题{query}"
        if not context and similarity_context:
            full_query = f" 输入的问题{query}\\尽量基于提供的菜品信息回答问题：\n 当前查询到的菜品信息是{similarity_context}"

        response = llm_call(full_query, instruction)

        # return {
        #     "recommendation": response,
        #     "menu_ids": pinecone_result["ids"]
        # }

        # 新增：从大模型返回的response中提取推荐菜品ID
        def extract_recommended_menu_ids(response_text):
            pattern = r'\*{0,2}菜品ID\*{0,2}\s*[:：]\s*(\d+)'
            matches = re.findall(pattern, response_text)
            return list(dict.fromkeys(matches))  # 去重后返回

        extracted_menu_ids = extract_recommended_menu_ids(response)
        return {
            "recommendation": response,
            "menu_ids": extracted_menu_ids  # 替换为提取出的ID列表
        }

    except Exception as e:
        raise ToolException(f"菜品查询工具调用失败{str(e)}")


# 配送返回检查工具
@tool
def delivery_check_tool(address: str, travel_mode: int = None) -> str:
    """
        配送范围检查工具

        检查指定地址是否在配送范围内，并提供距离信息。

        Args:
            address: 配送地址
            travel_mode: 距离计算方式 (0=直线距离, 1=驾车距离, 2=骑行距离)

        Returns:
            str: 配送检查结果的格式化信息

        Raises:
            ToolException: 当配送检查失败时
        """
    try:
        if travel_mode is None:
            travel_mode = 2

        mode_map = {
            0: DistanceMode.STRAIGHT,
            1: DistanceMode.DRIVING,
            2: DistanceMode.RIDING
        }

        mode_name = {
            0: "直线距离",
            1: "驾车距离",
            2: "骑行距离"
        }

        mode = mode_map.get(travel_mode)
        mode_name = mode_name.get(travel_mode)

        result = check_delivery_range(address, mode)

        if result["status"] == "success":
            status_text = "可以配送" if result["in_range"] else "超出配送范围"

            response = f"""
                配送信息查询结果:
                配送地址: {result['formatted_address']}
                配送距离: {result['distance']}公里 ({mode_name})
                配送状态: {status_text}
            """.strip()
        else:
            response = f"配送查询失败{result['message']}"
        return response
    except Exception as e:
        raise ToolException(f"配送距离查询工具调用失败{str(e)}")


if __name__ == '__main__':
    # load_prompt("general_inquiry")
    # print(general_inquiry("当前餐厅的位置在哪里距离南昌市江西财经大学麦庐园校区多远？"))

    # general_result = general_inquiry.invoke({"query": "请问你们餐厅的营业时间？"})
    # print(general_result)

    # menu_result = menu_inquiry.invoke({"query": "请你推荐一些减脂的菜系"})
    # print(f"推荐描述{menu_result['recommendation'][:200]}")

    delivery_check_result = delivery_check_tool.invoke(
        {"address": "江西省南昌市新建区江西财经大学麦庐园校区(南门)", "travel_mode": 1})
    print(f"配送信息: {delivery_check_result}")
